#ifndef SET_INCLUDED
#define SET_INCLUDED
#define T Set_T
typedef struct T *T;
/*==================== allocate and free ==================*/
/**
 * @brief creat a new set
 *
 * @param hint a estimation of the number of set
 * @param cmp comparation
 * @param hash hash function
 * @return T
 */
extern T Set_new(int hint,
                 int cmp(const void *x, const void *y),
                 unsigned hash(const void *x));
extern void Set_free(T *set);

/*==================== basic operation functions ====================*/
extern int Set_length(T set);
/**
 * @brief check if a member is or not in the set
 *
 * @param set
 * @param member
 * @return int 1 - member is in set; 0 - member is not in set
 */
extern int Set_member(T set, const void *member);
extern void Set_put(T set, const void *member);
extern void *Set_remove(T set, const void *member);

/**
 * @brief apply function to every element
 *
 * @param set
 * @param apply
 * @param cl
 */
extern void Set_map(T set,
                    void apply(const void *member, void *cl), void *cl);
extern void **Set_toArray(T set, void *end);

/*==================== 4 operations ====================*/
// s+t
extern T Set_union(T s, T t);
// s*t
extern T Set_inter(T s, T t);
// s-t
extern T Set_minus(T s, T t);
// s/t
extern T Set_diff(T s, T t);

#undef T
#endif
